package com.yang.newRetail.service;

import com.yang.newRetail.dao.*;
import com.yang.newRetail.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class ShareProfitService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MembershipLevelMapper membershipLevelMapper;

    @Autowired
    private SharingProfitSettingsMapper sharingProfitSettingsMapper;

    @Autowired
    private RetailProfitMapper retailProfitMapper;

    @Autowired
    private SalesProfitMapper salesProfitMapper;

    @Autowired
    private ManagementProfitMapper managementProfitMapper;

    @Autowired
    private AgentMapper agentMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private TurnoverMapper turnoverMapper;

    private static final ReentrantLock lock = new ReentrantLock();

    public void agentClassification(Agent agent, Orders order, String boundStoreId, float agencyAmount, boolean crossStore, boolean stopSign){

        lock.lock();

        Turnover turnover = new Turnover();
        turnover.setAmount(agencyAmount);
        turnover.setOrderId(order.getId());
        turnover.setUserId(agent.getUserId());
        turnover.setUserName(agent.getUserName());
        turnoverMapper.insert(turnover);

        lock.unlock();

        if(!agent.getUserId().equals("d258b92f-a33e-11eb-b85c-5405db357c9f")){
            if (!agent.getSuperiorAgencyId().equals("")){
                Agent superiorAgent = agentMapper.selectById(agent.getSuperiorAgencyId());
                agentClassification(superiorAgent, order, "", turnover.getAmount()/2, crossStore, stopSign);
            }else {
                if(crossStore && stopSign){
                    Store store = storeMapper.selectById(boundStoreId);
                    Agent crossStoreAgent = agentMapper.selectById(store.getAgentId());
                    agentClassification(crossStoreAgent, order, boundStoreId, turnover.getAmount()/2, crossStore, stopSign);
                    stopSign = false;
                }
            }
        }
    }

    public void vipClassification(Users subordinateUser, Users superiorUser, int ordinary, int Joint, int partner, Orders order, String boundStoreId, boolean crossStore, MembershipLevel[] membershipLevels, SharingProfitSettings sharingProfitSettings){

        lock.lock();

        if (superiorUser.getVipLevel() == 0){
            ordinary += 1;
            if (ordinary == 1){
                superiorUser.setIntegral(superiorUser.getIntegral() + order.getAmount());
                userMapper.updateById(superiorUser);
            }
        }

        Store store = storeMapper.selectById(order.getStoreId());

        if(superiorUser.getVipLevel() == 1){
            Joint += 1;
            if (Joint == 1){
                RetailProfit retailProfit = new RetailProfit();
                retailProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) (membershipLevels[1].getSharingProfitRatio() / 100));
                retailProfit.setOrderId(order.getId());
                retailProfit.setUserId(superiorUser.getId());
                retailProfit.setUserName(superiorUser.getName());
                retailProfitMapper.insert(retailProfit);
            }

            Users superiorUserAgain = userMapper.selectById(superiorUser.getRecommendedUserId());
            if(superiorUserAgain.getAgentLevel() != 0 && superiorUserAgain.getVipLevel() != 3){
                Agent agent = agentMapper.selectById(store.getAgentId());
                agentClassification(agent, order, boundStoreId, (order.getAmount() - order.getCollectionPrice()) * (float) (sharingProfitSettings.getAgencyPercentage() / 100/2), crossStore, true);
            }
        }

        if (superiorUser.getVipLevel() == 2){
            partner += 1;
            if (partner == 1){
                SalesProfit salesProfit = new SalesProfit();

                if(subordinateUser.getVipLevel() != 0) {
                    salesProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) ((membershipLevels[2].getSharingProfitRatio() - membershipLevels[1].getSharingProfitRatio()) / 100));
                }else{
                    salesProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) (membershipLevels[2].getSharingProfitRatio() / 100));
                }

                salesProfit.setOrderId(order.getId());
                salesProfit.setUserId(superiorUser.getId());
                salesProfit.setUserName(superiorUser.getName());
                salesProfitMapper.insert(salesProfit);
            }

            Users superiorUserAgain = userMapper.selectById(superiorUser.getRecommendedUserId());
            if(superiorUserAgain.getAgentLevel() != 0 && superiorUserAgain.getVipLevel() != 3){
                Agent agent = agentMapper.selectById(store.getAgentId());
                agentClassification(agent, order, boundStoreId, (order.getAmount() - order.getCollectionPrice()) * (float) (sharingProfitSettings.getAgencyPercentage() / 100/2), crossStore, true);
            }
        }

        if (superiorUser.getVipLevel() == 3){
            if(crossStore){
                ManagementProfit bindingManagementProfit = new ManagementProfit();

                if(subordinateUser.getVipLevel() != 0) {
                    bindingManagementProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) ((100 - sharingProfitSettings.getAgencyPercentage() - sharingProfitSettings.getUnboundStores() - membershipLevels[2].getSharingProfitRatio()) / 100));
                }else{
                    bindingManagementProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) ((100 - sharingProfitSettings.getAgencyPercentage() - sharingProfitSettings.getUnboundStores()) / 100));
                }

                bindingManagementProfit.setOrderId(order.getId());
                bindingManagementProfit.setUserId(superiorUser.getId());
                bindingManagementProfit.setUserName(superiorUser.getName());
                managementProfitMapper.insert(bindingManagementProfit);

                ManagementProfit unboundManagementProfit = new ManagementProfit();
                unboundManagementProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) (sharingProfitSettings.getUnboundStores() / 100));
                unboundManagementProfit.setOrderId(order.getId());
                unboundManagementProfit.setUserId(store.getUserId());
                unboundManagementProfit.setUserName(store.getUserName());
                managementProfitMapper.insert(unboundManagementProfit);

            }else {
                ManagementProfit managementProfit = new ManagementProfit();

                if(subordinateUser.getVipLevel() != 0) {
                    managementProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) ((100 - sharingProfitSettings.getAgencyPercentage() - membershipLevels[2].getSharingProfitRatio()) / 100));
                }else{
                    managementProfit.setAmount((order.getAmount() - order.getCollectionPrice()) * (float) ((100 - sharingProfitSettings.getAgencyPercentage()) / 100));
                }

                managementProfit.setOrderId(order.getId());
                managementProfit.setUserId(superiorUser.getId());
                managementProfit.setUserName(superiorUser.getName());
                managementProfitMapper.insert(managementProfit);
            }

            Agent agent = agentMapper.selectById(store.getAgentId());
            agentClassification(agent, order, boundStoreId, (order.getAmount() - order.getCollectionPrice()) * (float) (sharingProfitSettings.getAgencyPercentage() / 100/2), crossStore, true);

        }else{
            Users superiorUserAgain = userMapper.selectById(superiorUser.getRecommendedUserId());
            vipClassification(superiorUser, superiorUserAgain, ordinary, Joint, partner, order, "", crossStore, membershipLevels, sharingProfitSettings);
        }

        lock.unlock();
    }

    @Transactional
    public Map<String, Object> calculateProfit(String orderId){

        int ordinary = 0;
        int Joint = 0;
        int partner = 0;

        Orders order = orderMapper.selectById(orderId);
        Users user = userMapper.selectById(order.getUserId());
        Users superiorUser = userMapper.selectById(user.getRecommendedUserId());
        MembershipLevel membershipLevel1 = membershipLevelMapper.queryMembershipByLevel(1);
        MembershipLevel membershipLevel2 = membershipLevelMapper.queryMembershipByLevel(2);
        MembershipLevel[] MembershipLevels =new MembershipLevel[]{membershipLevel1, membershipLevel2};

        SharingProfitSettings sharingProfitSettings = sharingProfitSettingsMapper.querySharingProfitSettings();

        if (user.getBoundStoreId().equals(order.getStoreId())){
            vipClassification(user, superiorUser, ordinary, Joint, partner, order, "", false, MembershipLevels, sharingProfitSettings);
        }else{
            vipClassification(user, superiorUser, ordinary, Joint, partner, order, user.getBoundStoreId() ,true, MembershipLevels, sharingProfitSettings);
        }

        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("massage", "分润计算成功");
        msg.put("code", 200);
        return msg;
    }
}
